package com.woniuxy.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.redis.util.RedisKey;
import com.woniuxy.redis.util.RedisUtil;
import com.woniuxy.user.client.AdminFeignClient;
import com.woniuxy.user.entity.UserInfo;
import com.woniuxy.user.entity.UserScore;
import com.woniuxy.user.form.*;
import com.woniuxy.user.service.exception.LoginException;
import com.woniuxy.user.service.exception.RegistException;
import com.woniuxy.user.entity.UserAccount;
import com.woniuxy.user.service.exception.UserException;
import com.woniuxy.user.mapper.UserAccountMapper;
import com.woniuxy.user.mapper.UserInfoMapper;
import com.woniuxy.user.mapper.UserScoreMapper;
import com.woniuxy.user.service.UserAccountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.user.dto.UserDto;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ...
 * @since 2024年05月22日
 */
@Service
public class UserAccountServiceImpl extends ServiceImpl<UserAccountMapper, UserAccount> implements UserAccountService {


    @Resource
    private AdminFeignClient adminFeignClient;
    @Resource
    private RedisUtil redisUtil;
    @Resource
   private RabbitTemplate rabbitTemplate;
    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private UserScoreMapper userScoreMapper;

    @Resource
    private UserAccountMapper userAccountMapper;
    /**
     * 发送用户注册短信验证码
     * @param userPhone 手机号
     */
    @Override
    public void sendUserRegist(String userPhone) {
        if (redisUtil.hasKey(RedisKey.phoneCodeOneMinuteKey(userPhone))) {
            throw new RegistException(40001, "1分钟内不能重复发送");
        }
        if (redisUtil.hasKey(RedisKey.fiveMssageKey(userPhone))) {
            int num = Integer.parseInt(redisUtil.get(RedisKey.fiveMssageKey(userPhone)));
            if (num >= 5) {
                throw new RegistException(40001, "发送次数达到上限");
            }
        }
        QueryWrapper<UserAccount> wrapper = new QueryWrapper<UserAccount>();
        wrapper.eq("user_phone", userPhone);
        UserAccount user = this.getOne(wrapper);
        if (user != null) {
            throw new RegistException(60001, "手机号已注册");
        }
        //手机号存入消息队列中 由消费者来监听处理
        rabbitTemplate.convertAndSend("register_code_queue",userPhone);
    }

    /**
     * 用户注册
     * @param form 注册用户账号参数
     */
    @Override
    public void registUserAccount(RegistUserAccountForm form) {
        if (redisUtil.hasKey(RedisKey.codeErrorNumber(form.getUserPhone()))) {
            if ((Integer.parseInt(redisUtil.get(RedisKey.codeErrorNumber(form.getUserPhone())))) >= 5) {
                throw new RegistException(50003, "验证码已错5次");
            }
        }
        if (!form.getUserCode().equals(redisUtil.get(RedisKey.UserRegistCodeKey(form.getUserPhone())))) {
            if (redisUtil.hasKey(RedisKey.codeErrorNumber(form.getUserPhone()))) {
                redisUtil.insr(RedisKey.codeErrorNumber(form.getUserPhone()));
                if ((Integer.parseInt(redisUtil.get(RedisKey.codeErrorNumber(form.getUserPhone())))) >= 5) {
                    redisUtil.del(RedisKey.codeErrorNumber(form.getUserPhone()));
                }
            } else {
                redisUtil.set(RedisKey.codeErrorNumber(form.getUserPhone()), "1", 5 * 60);
            }
            throw new RegistException(50001, "验证码错误");
        }
        UserAccount userAccount = BeanUtil.toBean(form, UserAccount.class);
        userAccount.setState(0);
        this.save(userAccount);
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userAccount.getUserId());
        userInfo.setUserPhone(form.getUserPhone());
        userInfo.setNickName(form.getNickName());
        userInfo.setUserHeader("xxxxxxx");
        userInfo.setUserIntegral(100);
        userInfoMapper.insert(userInfo);
        UserScore userScore = new UserScore();
        userScore.setUserId(userAccount.getUserId());
        userScore.setChangeScore(100);
        userScore.setChangeDetails("用户首次注册,系统赠送");
        userScore.setScoreTotal(100);
        userScore.setChangeTime(LocalDateTime.now());
        userScoreMapper.insert(userScore);
    }

    /**
     * 发送登录验证码
     * @param userPhone 手机号
     */
    @Override
    public void sendLoginCode(String userPhone) {
        if (redisUtil.hasKey(RedisKey.phoneCodeOneMinuteKey(userPhone))) {
            throw new RegistException(10004, "1分钟内不能重复发送");
        }
        if (redisUtil.hasKey(RedisKey.fiveMssageKey(userPhone))) {
            int num = Integer.parseInt(redisUtil.get(RedisKey.fiveMssageKey(userPhone)));
            if (num >= 5) {
                throw new RegistException(10005, "发送次数达到上限");
            }
        }
        //手机号存入消息队列中 由消费者来监听处理
        rabbitTemplate.convertAndSend("login_code_queue",userPhone);
    }

    /**
     *用户验证码登录
     * @param form 用户登录参数
     * @return
     */
    @Override
    public UserDto userCodeLogin(UserCodeLoginForm form) {
        if (redisUtil.hasKey(RedisKey.codeErrorNumber(form.getUserPhone()))) {
            if ((Integer.parseInt(redisUtil.get(RedisKey.codeErrorNumber(form.getUserPhone())))) >= 5) {
                throw new LoginException(10002, "验证码已错5次,请重新发送");
            }
        }
        if (!form.getUserCode().equals(redisUtil.get(RedisKey.UserLoginCodeKey(form.getUserPhone())))) {
            if (redisUtil.hasKey(RedisKey.codeErrorNumber(form.getUserPhone()))) {
                redisUtil.insr(RedisKey.codeErrorNumber(form.getUserPhone()));
                if ((Integer.parseInt(redisUtil.get(RedisKey.codeErrorNumber(form.getUserPhone())))) >= 5) {
                    redisUtil.del(RedisKey.UserLoginCodeKey(form.getUserPhone()));
                }
            } else {
                redisUtil.set(RedisKey.codeErrorNumber(form.getUserPhone()), "1", 5 * 60);
            }
            throw new LoginException(10001, "验证码错误");
        }
        QueryWrapper<UserAccount>wrapper=new QueryWrapper<>();
        wrapper.eq("user_phone",form.getUserPhone());
        UserAccount userAccount = this.getOne(wrapper);
        if(userAccount==null){
            UserAccount account = new UserAccount();
            account.setUserName("用户");
            account.setUserPhone(form.getUserPhone());
            account.setUserPass("user");
            userAccount.setState(0);
            this.save(account);
            UserInfo userInfo = new UserInfo();
            userInfo.setUserId(account.getUserId());
            userInfo.setUserPhone(form.getUserPhone());
            userInfo.setNickName("用户");
            userInfo.setUserHeader("xxxxxxx");
            userInfo.setUserIntegral(100);
            userInfoMapper.insert(userInfo);
            UserScore userScore = new UserScore();
            userScore.setUserId(account.getUserId());
            userScore.setChangeScore(100);
            userScore.setChangeDetails("用户首次注册,系统赠送");
            userScore.setScoreTotal(100);
            userScore.setChangeTime(LocalDateTime.now());
            userScoreMapper.insert(userScore);

        }
        if(userAccount.getState()!=0) throw new LoginException(10001,"用户状态已被禁用");
        UserDto dto = new UserDto();
        dto.setUserId(userAccount.getUserId());
        dto.setUserName(userAccount.getUserName());
        return dto;
    }

    /**
     *用户账号密码登录
     * @param form 用户登录参数
     * @return
     */
    @Override
    public UserDto userLogin(UserLoginForm form) {
        UserAccount userAccount = this.getOne(new QueryWrapper<UserAccount>().eq("user_name", form.getUserName()));
        if(userAccount==null) throw new LoginException(1002,"用户名不存在");
        if(!userAccount.getUserPass().equals(form.getUserPass())) throw new LoginException(1002,"密码错误");
        if(userAccount.getState()!=0) throw new LoginException(10001,"用户状态已被禁用");
        UserDto dto = new UserDto();
        dto.setUserId(userAccount.getUserId());
        dto.setUserName(userAccount.getUserName());
        return dto;
    }

    /**
     * 修改用户状态
     * @param userId
     * @param state
     */
    @Override
    public void updateUserState(Integer userId, Integer state) {
        UserAccount userAccount = this.getById(userId);
        if(userAccount==null) throw new UserException(10001,"用户不存在");
        if(state!=0&&state!=1) throw new UserException(10002,"状态有误");
        userAccount.setState(state);
        this.updateById(userAccount);
    }

    /**
     * 发送用户修改手机短信验证码
     * @param userPhone 手机号
     */

    @Override
    public void sendUserUpdatePhone(Integer userId,String userPhone) {
        UserAccount userAccount = this.getOne(new QueryWrapper<UserAccount>().eq("user_id", userId).eq("user_phone", userPhone));
        if(userAccount==null) throw new UserException(10001,"用户账号和手机不相匹配");
        if (redisUtil.hasKey(RedisKey.phoneCodeOneMinuteKey(userPhone))) {
            throw new RegistException(40001, "1分钟内不能重复发送");
        }
        if (redisUtil.hasKey(RedisKey.fiveMssageKey(userPhone))) {
            int num = Integer.parseInt(redisUtil.get(RedisKey.fiveMssageKey(userPhone)));
            if (num >= 5) {
                throw new RegistException(40001, "发送次数达到上限");
            }
        }
        QueryWrapper<UserAccount> wrapper = new QueryWrapper<UserAccount>();
        wrapper.eq("user_phone", userPhone);
        UserAccount user = this.getOne(wrapper);
        if (user == null) {
            throw new RegistException(60001, "手机号不存在");
        }
        //手机号存入消息队列中 由消费者来监听处理
        rabbitTemplate.convertAndSend("update_phone_code_queue",userPhone);
    }

    /**
     * 发送用户新手机验证码
     * @param userId
     * @param userPhone 手机号
     */
    @Override
    public void sendUserUpdateNewPhone(Integer userId, String userPhone) {
        if (redisUtil.hasKey(RedisKey.phoneCodeOneMinuteKey(userPhone))) {
            throw new RegistException(40001, "1分钟内不能重复发送");
        }
        if (redisUtil.hasKey(RedisKey.fiveMssageKey(userPhone))) {
            int num = Integer.parseInt(redisUtil.get(RedisKey.fiveMssageKey(userPhone)));
            if (num >= 5) {
                throw new RegistException(40001, "发送次数达到上限");
            }
        }
        //手机号存入消息队列中 由消费者来监听处理
        rabbitTemplate.convertAndSend("update_new_phone_code_queue",userPhone);
    }

    /**
     * 修改用户手机
     * @param userId
     * @param form
     */
    @Override
    public void userUpdatePhone(Integer userId, UserUpdatePhoneForm form) {
        if (redisUtil.hasKey(RedisKey.codeErrorNumber(form.getOldPhone()))) {
            if ((Integer.parseInt(redisUtil.get(RedisKey.codeErrorNumber(form.getOldPhone())))) >= 5) {
                throw new LoginException(10002, "验证码已错5次,请重新发送");
            }
        }
        if (!form.getOldPhoneCode().equals(redisUtil.get(RedisKey.UserUpdatePhoneCodeKey(form.getOldPhone())))) {
            if (redisUtil.hasKey(RedisKey.codeErrorNumber(form.getOldPhone()))) {
                redisUtil.insr(RedisKey.codeErrorNumber(form.getOldPhone()));
                if ((Integer.parseInt(redisUtil.get(RedisKey.codeErrorNumber(form.getOldPhone())))) >= 5) {
                    redisUtil.del(RedisKey.UserUpdatePhoneCodeKey(form.getOldPhone()));
                }
            } else {
                redisUtil.set(RedisKey.codeErrorNumber(form.getOldPhone()), "1", 5 * 60);
            }
            throw new LoginException(10001, "老手机验证码错误");
        }

        if (redisUtil.hasKey(RedisKey.codeErrorNumber(form.getNewPhone()))) {
            if ((Integer.parseInt(redisUtil.get(RedisKey.codeErrorNumber(form.getNewPhone())))) >= 5) {
                throw new LoginException(10002, "验证码已错5次,请重新发送");
            }
        }
        if (!form.getNewPhoneCode().equals(redisUtil.get(RedisKey.UserUpdateNewPhoneCodeKey(form.getNewPhone())))) {
            if (redisUtil.hasKey(RedisKey.codeErrorNumber(form.getNewPhone()))) {
                redisUtil.insr(RedisKey.codeErrorNumber(form.getNewPhone()));
                if ((Integer.parseInt(redisUtil.get(RedisKey.codeErrorNumber(form.getNewPhone())))) >= 5) {
                    redisUtil.del(RedisKey.UserUpdateNewPhoneCodeKey(form.getNewPhone()));
                }
            } else {
                redisUtil.set(RedisKey.codeErrorNumber(form.getNewPhone()), "1", 5 * 60);
            }
            throw new LoginException(10001, "新手机验证码错误");
        }

        UserAccount userAccount = this.getById(userId);
        userAccount.setUserPhone(form.getNewPhone());
        UserInfo userInfo = userInfoMapper.selectOne(new QueryWrapper<UserInfo>().eq("user_id", userId));
        userInfo.setUserPhone(form.getNewPhone());
        this.updateById(userAccount);
        userInfoMapper.updateById(userInfo);
    }

    /**
     * 修改密码
     *
     * @param userId
     * @param form
     */
    @Override
    public void userUpdatePass(Integer userId, UserUpdatePassForm form) {
        UserAccount userAccount = this.getById(userId);
        if(userAccount==null) throw new UserException(10001,"用户不存在");

        if (!userAccount.getUserPass().equals(form.getOldPass())) {
            throw new UserException(10001,"老密码错误");
        }
        userAccount.setUserPass(form.getNewPass());
        this.updateById(userAccount);
    }
}
